package com.healthcloud.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

/**
 * 
 * @author lixx http异步处理
 *
 */
public class HttpAsyncUtil {
	public static void sendPost(String url, String json,
			final String encoding, final AsyncHandler handler)
			throws KeyManagementException, UnsupportedEncodingException {
		final CloseableHttpAsyncClient  client = HttpAsyncClients.createDefault();
		//创建post方式请求对象  
        HttpPost httpPost = new HttpPost(url);
        //装填参数  
        StringEntity s = new StringEntity(json.toString(), encoding);
        s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"application/json"));
        //设置参数到请求对象中  
        httpPost.setEntity(s);  
        System.out.println("请求地址："+url);  
        System.out.println("请求参数："+json.toString()); 
        //httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");  
        httpPost.setHeader("Content-type", "text/plain;charset=UTF-8");
        httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); 
        client.start();
        //执行请求操作，并拿到结果（异步）  
        client.execute(httpPost, new FutureCallback<HttpResponse>() {  
              
            @Override  
            public void failed(Exception ex) {  
                handler.failed(ex);  
                close(client);  
            }  
              
            @Override  
            public void completed(HttpResponse resp) {  
                String body="";  
                //这里使用EntityUtils.toString()方式时会大概率报错，原因：未接受完毕，链接已关  
                try {  
                    HttpEntity entity = resp.getEntity();  
                    if (entity != null) {  
                        final InputStream instream = entity.getContent();  
                        try {  
                            final StringBuilder sb = new StringBuilder();  
                            final char[] tmp = new char[1024];  
                            final Reader reader = new InputStreamReader(instream,encoding);  
                            int l;  
                            while ((l = reader.read(tmp)) != -1) {  
                                sb.append(tmp, 0, l);  
                            }  
                            body = sb.toString();  
                        } finally {  
                            instream.close();  
                            EntityUtils.consume(entity);  
                        }  
                    }  
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  
                handler.completed(body);  
                close(client);  
            }  
              
            @Override  
            public void cancelled() {  
                handler.cancelled();  
                close(client);  
            }  
        });
	}
	
	 /** 
     * 关闭client对象 
     *  
     * @param client 
     */  
    private static void close(CloseableHttpAsyncClient client) {  
        try {  
            client.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    } 
    
	public static class AsyncHandler implements IHandler{  
        
        @Override  
        public Object failed(Exception e) {  
            System.err.println(Thread.currentThread().getName()+"--失败了--"+e.getClass().getName()+"--"+e.getMessage());  
            return null;  
        }  
        @Override  
        public Object completed(String respBody) {  
            System.out.println(Thread.currentThread().getName()+"--获取内容："+respBody);  
            return null;  
        }  
        @Override  
        public Object cancelled() {  
            System.out.println(Thread.currentThread().getName()+"--取消了");  
            return null;  
        }  
    }  
      
    /** 
     * 回调处理接口 
     * @version 1.0 
     */  
    public interface IHandler {  
          
        /** 
         * 处理异常时，执行该方法 
         * @return 
         */  
        Object failed(Exception e);  
          
        /** 
         * 处理正常时，执行该方法 
         * @return 
         */  
        Object completed(String respBody);  
          
        /** 
         * 处理取消时，执行该方法 
         * @return 
         */  
        Object cancelled();  
    }  
}
